package model

import (
	"My-Blog/utils"
	"My-Blog/utils/errmsg"
	"context"
	"fmt"
	"io"             //// 输入输出操作
	"mime/multipart" //用于处理multipart/form-data类型的表单数据
	"os"             //操作系统功能
	"strings"        //字符串处理

	"github.com/qiniu/go-sdk/v7/auth/qbox" //提供七牛云的认证功能，用于生成和管理认证凭证
	"github.com/qiniu/go-sdk/v7/storage"   //提供对象存储的核心功能，包括上传文件，管理存储空间，处理文件等
)

var AccessKey = utils.AccessKey //七牛云的AccessKey
var SecretKey = utils.SecretKey //七牛云的SecretKey
var Bucket = utils.Bucket       //七牛云存储空间名称
var ImgUrl = utils.QiniuSever   //七牛云CDN域名或存储域名

func UploadFile(file multipart.File, fileSize int64) (string, int) {
	// 重置文件指针到开头
	//file.Seek（）第一个参数是偏移量，第二个是基准位置，返回两个值，一个是新的偏移量，一个是错误
	if _, err := file.Seek(0, io.SeekStart); err != nil {
		return "", errmsg.ERROR
	}

	// 创建临时文件保存multipart.File内容（即上传的内容）
	//参数""表示使用系统默认的临时文件目录
	//参数"upload-*.tmp"是文件名模板，*会被替换成随机字符串，确保文件名唯一
	tempFile, err := os.CreateTemp("", "upload-*.tmp")
	if err != nil {
		fmt.Printf("创建临时文件失败: %v\n", err)
		return "", errmsg.ERROR
	}
	defer os.Remove(tempFile.Name()) // 确保临时文件会被删除

	// 将multipart.File内容复制到临时文件
	//io.Copy()返回两个值，一个是复制的字节数，一个是错误
	if _, err := io.Copy(tempFile, file); err != nil {
		fmt.Printf("复制文件内容失败: %v\n", err)
		return "", errmsg.ERROR
	}
	tempFile.Close() //关闭之前创建的临时文件，以便进行后续操作

	//创建上传策略
	putPolicy := storage.PutPolicy{
		Scope:   Bucket, //指定上传的存储空间
		Expires: 3600,   //上传凭证的有效期（秒）
	}
	//生成上传凭证
	mac := qbox.NewMac(AccessKey, SecretKey) //使用AccessKey和SecretKey创建Mac对象
	upToken := putPolicy.UploadToken(mac)    //生成上传凭证

	//配置上传参数
	cfg := storage.Config{
		UseCdnDomains: false, //是否使用CDN加速域名
		UseHTTPS:      false, //是否使用HTTPS
	}

	//自动获取存储区域
	region, err := storage.GetRegion(AccessKey, Bucket)
	if err != nil {
		fmt.Printf("自动获取区域失败，使用默认华北区域: %v\n", err)
		cfg.Zone = &storage.ZoneHuabei // 自动获取失败时使用默认华北区域
	} else {
		cfg.Zone = region // 自动获取成功则使用获取到的区域
	}

	//执行文件上传
	putExtra := storage.PutExtra{}                //额外的上传参数（这里使用默认值）
	formUploader := storage.NewFormUploader(&cfg) //创建表单上传对象
	ret := storage.PutRet{}                       //用于接收上传成功后的返回信息
	//执行上传（不指定key，由七牛云自动生成文件名）
	//PutFileWithoutKey表示不指定文件名，由七牛云自动生成唯一的 key
	err = formUploader.PutFileWithoutKey(context.Background(), &ret, upToken, tempFile.Name(), &putExtra)
	if err != nil {
		fmt.Printf("上传错误详情: %v\n", err)
	}

	//生成文件访问URL
	url := strings.TrimSuffix(ImgUrl, "/") + "/" + ret.Key
	return url, errmsg.SUCCSE
}
